﻿// -----------------------------------------------------------------------
// <copyright file="SerializationService.cs" company="Intermedia.NET">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

using System.Text;
using RayDen.Library.Core.Primitives;
using RayDen.Library.Entity.Frames;

namespace RayDen.Library.Data.Xml {
    using System;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization;

    public class SerializationService {
        public static byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }

        public static string GetString(byte[] bytes, int offset, int size)
        {
            var chars = new char[size / sizeof(char)];
            Buffer.BlockCopy(bytes, offset, chars, 0, size);
            return new string(chars);
        }

        public static string Serialize(object obj, params Type[] knownTypes) {
            using (var memoryStream = new MemoryStream())
            using (var reader = new StreamReader(memoryStream)) {
                var serializer = new DataContractSerializer(obj.GetType(), knownTypes);
                serializer.WriteObject(memoryStream, obj);
                memoryStream.Position = 0;
                return reader.ReadToEnd();
            }
        }

        public static string SerializeItems(object obj, Type[] knownTypes)
        {
            using (var memoryStream = new MemoryStream())
            using (var reader = new StreamReader(memoryStream))
            {
                var serializer = new DataContractSerializer(obj.GetType(), knownTypes);
                serializer.WriteObject(memoryStream, obj);
                memoryStream.Position = 0;
                return reader.ReadToEnd();
            }
        }
        public static string SerializeKnown(object obj)
        {
            using (var memoryStream = new MemoryStream())
            using (var reader = new StreamReader(memoryStream))
            {
                var serializer = new DataContractSerializer(obj.GetType(), new[] {
                                                    typeof (Vector), typeof (RgbSpectrum),
                                                    typeof (FrameElement), typeof (FrameCamera), typeof (FrameLightsource), typeof (FrameObjFileReference),
                                                    typeof (FrameSceneDataReference),
                                                    typeof (Frame3DsFileReference), typeof (FrameVolumeArea)
                                                });
                serializer.WriteObject(memoryStream, obj);
                memoryStream.Position = 0;
                return reader.ReadToEnd();
            }
        }

        public static object Deserialize(string xml, Type toType) {
            return Deserialize(xml, toType, new[] {
                                                    typeof (Vector), typeof (RgbSpectrum),
                                                    typeof (FrameElement), typeof (FrameCamera), typeof (FrameLightsource), typeof (FrameObjFileReference),
                                                    typeof (FrameSceneDataReference),
                                                    typeof (Frame3DsFileReference), typeof (FrameVolumeArea)
                                                });
        }


        public static object Deserialize(string xml, Type toType, Type[] knownTypes) {
            using (Stream stream = new MemoryStream()) {
                byte[] data = Encoding.UTF8.GetBytes(xml);
                stream.Write(data, 0, data.Length);
                stream.Position = 0;
                var deserializer = new DataContractSerializer(toType, knownTypes.Union(new[]{typeof (Vector), typeof (RgbSpectrum)}));
                return deserializer.ReadObject(stream);
            }
        }
    }
}
